import { ComponentClass } from 'react'
import Taro, { Component } from '@tarojs/taro'
import { View, Text, Picker } from '@tarojs/components'
import { connect } from '@tarojs/redux'

import { default as ProductUtils } from '../../utils/product'
import { User as UserUtils } from '../../utils/user'
import { Utils } from '../../utils/utils'
import Constants from '../../config/constants'

import './index.scss'

const productUtils = new ProductUtils()
const userUtils = new UserUtils()
const utils = new Utils()

type PageStateProps = {}

type PageDispatchProps = {}

type PageOwnProps = {
  regionRange: 1 | 2 | 3,  // 省市区的选项， 枚举值 1: 省 2: 省市 3: 省市区
  regionCode?: string[],   // 默认选中的省市区code
  eventRandom: string,     // change事件后缀字符串
}

type PageState = {
  regionOptions: any,      // 省市区选项
  lastRegionOptions: any,  // 最后选中的省市区所在的选项
  selectRegionIndex: number[],  // 省市区的选中值下标
  pickerIndex: number[],   // picker当前显示选项的下标
  selectRegionName: any,   // 省市选中值的名称
  selectRegionCode: any,   // 省市选中值的code
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface RegionPicker {
  props: IProps;
  state: PageState;
}

/**
 * 省市区选择组件
 */
@connect(({ }) => ({}), (dispatch) => ({}))
class RegionPicker extends Component {

  constructor(props) {
    super(props);
    this.state = this.initRegionParam()
    // console.log('regionOptions = ', this.state.regionOptions)
  }

  componentDidMount() {

  }

  componentWillUnmount() { }

  componentWillReceiveProps(nextProps) {

    const curPropsStr = JSON.stringify(this.props)
    const nextPropsStr = JSON.stringify(nextProps)
    if (curPropsStr !== nextPropsStr) {
      const newState = this._getRegionParamByRegionCode(nextProps.regionCode, nextProps.regionRange)

      this.setState({
        ...newState
      })
    }
  }

  componentDidShow() { }

  componentDidHide() { }

  render() {
    let regionsDisplayName = ''
    if (this.state.selectRegionName) {
      regionsDisplayName = this.state.selectRegionName.join(' ')
    }

    return (<Picker
      className='region-picker'
      mode='multiSelector'
      onChange={this.onMultiplePickerChange}
      onColumnchange={this.onRegionColumnChange}
      onCancel={this.onRegionColumnCancel}
      value={this.state.pickerIndex}
      range={this.state.regionOptions} rangeKey="name">
      <View className="content">
        <View>
          <Text className="text">
            { // 没选中任何值时显示 placeholder
              !this.state.selectRegionName ? (<Text className="place-holder">请选择</Text>) : null
            }
            {
              regionsDisplayName
            }
          </Text>
        </View>
        <View>
          <Text className="iconfont icon-icon1"></Text>
        </View>
      </View>
    </Picker>)
  }

  /**
   * 多选picker的改变监听
   * @param name form表单项的name
   * @param e 
   */
  onMultiplePickerChange = (e) => {
    // console.log('onMultiplePickerChange, e = ', e)

    const detail = e.detail
    const selectIndex = detail.value
    const pickerIndex = [...selectIndex]
    const { regionOptions } = this.state

    if (selectIndex) {
      // 计算选中区域的 code 和 name
      const codeAndName = this._getRegionParamByIndex(selectIndex, regionOptions)
      const { selectRegionCode, selectRegionName } = codeAndName

      // 更新参数
      this.setState({
        selectRegionCode,
        selectRegionName,
        selectRegionIndex: selectIndex,
        pickerIndex,
        lastRegionOptions: [...regionOptions],
      }, () => {
        // console.log('onMultiplePickerChange state = ', this.state)
      })

      this.sendPickerChange(selectRegionCode, selectIndex, selectRegionName)
    }
  }

  /**
   * 多选picker的列改变监听
   * @param e 
   */
  onRegionColumnChange = (e) => {
    // console.log('onRegionColumnChange, e = ', e)

    const { column, value } = e.detail
    let { regionOptions, pickerIndex } = this.state
    const { regionRange } = this.props

    if (column === 0) {
      if (regionRange > 1) {
        const selectProvinceCode = utils.getOptionValueByIndex(value, this.state.regionOptions[0], 'key')
        regionOptions = utils.getInitRegionsById(selectProvinceCode)
        regionOptions = this._getRegionOptionsByRange(regionRange, regionOptions)
        pickerIndex[0] = value

        for(let i = 1; i < regionRange - 1; i++) {
           // 修改其余列选项下标为0
           pickerIndex[i] = 0
        }
      }
    } else if (column === 1) {
      if (regionRange >= 2) {
        const selectCityCode = utils.getOptionValueByIndex(value, this.state.regionOptions[1], 'key')
        regionOptions = utils.getInitRegionsById(utils.getOptionValueByIndex(pickerIndex[0], regionOptions[0], 'key'), selectCityCode)
        regionOptions = this._getRegionOptionsByRange(regionRange, regionOptions)
        pickerIndex[1] = value

        for(let i = 2; i < regionRange - 1; i++) {
          // 修改其余列选项下标为0
          pickerIndex[i] = 0
       }
      }
    }

    this.setState({
      regionOptions,
      pickerIndex,
    }, () => {
      // console.log('new regionOptions = ', this.state.regionOptions)
    })
  }

  /**
   * 多选picker取消的处理方法
   * @param e
   */
  onRegionColumnCancel = (e) => {
    // console.log('onRegionColumnCancel, e = ', e)

    let lastSelectIndex = this.state.selectRegionIndex
    let lastRegionOptions = this.state.lastRegionOptions

    // 没有已选中区域的情况下，pickerIndex 与 regionOptions 维持现状
    if (!this.state.selectRegionCode && !this.state.selectRegionName) {
      lastSelectIndex = this.state.pickerIndex
      lastRegionOptions = this.state.regionOptions
    }
    // console.log('onRegionColumnCancel, lastSelectIndex = ', lastSelectIndex)

    // 把选项和选中的参数更新为 lastRegionOptions
    this.setState({
      pickerIndex: [...lastSelectIndex],
      regionOptions: lastRegionOptions,
    }, () => {
      // console.log('onRegionColumnCancel, state = ', this.state)
    })
  }

  /**
   * 根据 regionRange 返回省市区选项
   * @param regionRange 枚举 1 | 2 |3
   * @param allRegions 当前的省市区选项
   */
  _getRegionOptionsByRange(regionRange: number, allRegions: any): any {
    // 初始化省市区选项
    let regionOptions = allRegions

    switch (regionRange) {
      case 1:
        regionOptions = [allRegions[0]]
        break
      case 2:
        regionOptions = [allRegions[0], allRegions[1]]
        break
      default:
        break
    }

    return regionOptions
  }

  /**
   * 根据选中的选项下标，获取省市区参数
   * @param selectRegionIndex 选中的省、市、区 下标
   * @param regionsOptions 省市区选项
   */
  _getRegionParamByIndex(selectRegionIndex: number[], regionsOptions: any): any {

    // 计算选中省市区code
    const selectRegionCode = selectRegionIndex.map((item, index) => {
      return regionsOptions[index][item]['key']
    })

    // 初始化选中省市区名称
    const selectRegionName = selectRegionIndex.map((item, index) => {
      return regionsOptions[index][item]['name']
    })

    return {
      selectRegionCode,
      selectRegionName,
    }
  }

  /**
   * 根据省市区code获取参数
   * @param regionCode 省市区code数组
   * @param regionRange 范围
   */
  _getRegionParamByRegionCode(regionCode: string[] | undefined, regionRange: number): any {

    const result = {}

    let allRegions = utils.getInitRegionsById()

    result['regionOptions'] = allRegions

    if (regionRange) {

      let regionCodeCopy: string[] = []

      // 根据传入的默认选中省市区参数regionCode 加载对应的选
      if (regionCode && regionCode.length > 0) {
        regionCodeCopy = [...regionCode]
        allRegions = utils.getInitRegionsById(...regionCode)
      }

      // 初始化省市区选项
      let regionOptions = this._getRegionOptionsByRange(regionRange, allRegions)
      // console.log('regionOptions = ', regionOptions)

      // 初始化最后一次选中的省市区所在选项
      let lastRegionOptions = [...regionOptions]

      // 初始化省市区默认选中值下标
      let selectRegionIndex = allRegions.map(item => {
        return 0
      })
      if (regionCodeCopy && regionCodeCopy.length > 0) {
        selectRegionIndex = regionCodeCopy.map((item, index) => {
          const regionIndex = utils.getOptionIndex(item, allRegions[index], 'key')
          return typeof regionIndex === 'number' ? regionIndex : parseInt(regionIndex)
        })
      }
      // console.log('selectRegionIndex = ', selectRegionIndex)

      // 初始化 pickerIndex
      let pickerIndex = [...selectRegionIndex]

      // 有 regionCode 的情况下，再初始化 code 和 name
      if (regionCodeCopy && regionCodeCopy.length > 0) {
        const codeAndName = this._getRegionParamByIndex(selectRegionIndex, allRegions)
        const { selectRegionCode, selectRegionName } = codeAndName

        Object.assign(result, {
          selectRegionCode,
          selectRegionName,
        })
      }

      Object.assign(result, {
        regionOptions,
        lastRegionOptions,
        selectRegionIndex,
        pickerIndex,
      })
    }

    return result
  }

  /**
   * 省市区组件数据初始化
   */
  initRegionParam(): any {
    let result = {}
    const { regionRange, regionCode } = this.props
    result = this._getRegionParamByRegionCode(regionCode, regionRange)
    return result
  }

  /**
   * 发射省市区picker组件change事件的方法
   * @param selectRegionCode 选中省市区code
   * @param selectRegionIndex 选中省市区下标
   * @param selectRegionName 选中省市区name
   */
  sendPickerChange(selectRegionCode: string[], selectRegionIndex: string[], selectRegionName: string[]) {
    Taro.eventCenter.trigger(`${Constants.REGION_PICKER_CHANGE_EVENT}${this.props.eventRandom}`, {
      selectRegionCode,
      selectRegionIndex,
      selectRegionName,
    })
  }

}
export default RegionPicker as ComponentClass<PageOwnProps, PageState>
